package com.sweetguy.util;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JwtUtil {

    //
    private static final String SECRET_KEY = "my-secret";
    //
    private static final String SUBJECT = "用户登录认证";
    //
    private static final String ISSUER = "SweetGuy";
    //
    private static final Date ISSUED_AT = new Date();
    //
    private static final Date EXPIRES_AT =
            new Date(System.currentTimeMillis() + (1000 * 60 * 60 * 2L));
    //
    private static final Long EXPIRATION_TIME_THRESHOLD = 1000*60 * 5L;

    public static String build(Long id, String name, String avatar) {
        if (ObjectUtil.hasNull(id, name, avatar)) {
            throw new RuntimeException("JWT存在null值负载");
        }
        JWTCreator.Builder builder = JWT.create();
        builder.withClaim("id", id);
        builder.withClaim("name", name);
        builder.withClaim("avatar", avatar);
        //
        builder.withClaim("created", System.currentTimeMillis());
        builder.withSubject(SUBJECT);
        builder.withIssuer(ISSUER);
        builder.withIssuedAt(ISSUED_AT);
        builder.withExpiresAt(EXPIRES_AT);
        return builder.sign(Algorithm.HMAC256(SECRET_KEY));
    }

    public static Map<String, Object> verify(String token) {
        Map<String, Object> result = new HashMap<>(4);
        if (StrUtil.isEmpty(token)) {
            throw new RuntimeException("token令牌为空");
        }
        //
        DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC256(SECRET_KEY)).build().verify(token);

        Long id = decodedJWT.getClaim("id").asLong();
        String name = decodedJWT.getClaim("name").asString();
        String avatar = decodedJWT.getClaim("avatar").asString();

        //
        if (decodedJWT.getExpiresAt().getTime() - System.currentTimeMillis() < EXPIRATION_TIME_THRESHOLD) {
            result.put("expiringSoon", true);
            result.put("newToken", build(id, name, avatar));
        }
        //
        else {
            result.put("id", id);
            result.put("name", name);
            result.put("avatar", avatar);
            result.put("expiringSoon", false);
        }

        return result;
    }
}
